#!/bin/bash

# YxYWeb 停止脚本
# 优雅关闭服务

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 项目配置
PROJECT_NAME="YxYWeb"
PROJECT_DIR=$(dirname "$(readlink -f "$0")")
PID_FILE="$PROJECT_DIR/yxyweb.pid"
LOG_FILE="$PROJECT_DIR/logs/yxyweb.log"
PORT=8000

# 检查服务是否运行
check_running() {
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null 2>&1; then
            return 0
        else
            log_warning "发现过期的PID文件，删除中..."
            rm -f "$PID_FILE"
        fi
    fi
    return 1
}

# 优雅停止服务
graceful_stop() {
    local pid=$1
    local timeout=${2:-30}
    
    log_info "发送SIGTERM信号到进程 $pid..."
    kill -TERM "$pid" 2>/dev/null || true
    
    # 等待进程优雅退出
    local count=0
    while [ $count -lt $timeout ]; do
        if ! ps -p "$pid" > /dev/null 2>&1; then
            log_success "进程已优雅退出"
            return 0
        fi
        sleep 1
        count=$((count + 1))
        echo -n "."
    done
    echo
    
    return 1
}

# 强制停止服务
force_stop() {
    local pid=$1
    
    log_warning "强制停止进程 $pid..."
    kill -KILL "$pid" 2>/dev/null || true
    
    # 等待进程被杀死
    sleep 2
    
    if ps -p "$pid" > /dev/null 2>&1; then
        log_error "无法停止进程 $pid"
        return 1
    else
        log_success "进程已被强制停止"
        return 0
    fi
}

# 通过端口停止服务
stop_by_port() {
    log_info "通过端口 $PORT 查找并停止服务..."
    
    # 查找占用端口的进程
    local pids=$(netstat -tuln 2>/dev/null | grep ":$PORT " | awk '{print $7}' | cut -d'/' -f1 | sort -u)
    
    if [ -z "$pids" ]; then
        log_info "端口 $PORT 未被占用"
        return 0
    fi
    
    for pid in $pids; do
        if [ -n "$pid" ] && [ "$pid" != "-" ]; then
            log_info "发现占用端口 $PORT 的进程: $pid"
            
            # 尝试优雅停止
            if graceful_stop "$pid" 10; then
                log_success "进程 $pid 已优雅停止"
            else
                log_warning "优雅停止失败，尝试强制停止..."
                if force_stop "$pid"; then
                    log_success "进程 $pid 已强制停止"
                else
                    log_error "无法停止进程 $pid"
                    return 1
                fi
            fi
        fi
    done
    
    return 0
}

# 清理PID文件
cleanup_pid() {
    if [ -f "$PID_FILE" ]; then
        rm -f "$PID_FILE"
        log_info "已删除PID文件"
    fi
}

# 显示服务状态
show_status() {
    if [ -f "$PID_FILE" ]; then
        PID=$(cat "$PID_FILE")
        if ps -p "$PID" > /dev/null 2>&1; then
            log_warning "服务仍在运行 (PID: $PID)"
            return 1
        else
            log_info "服务已停止"
            cleanup_pid
            return 0
        fi
    else
        log_info "服务未运行"
        return 0
    fi
}

# 显示帮助信息
show_help() {
    echo "用法: $0 [选项]"
    echo
    echo "选项:"
    echo "  stop      停止服务 (默认)"
    echo "  force     强制停止服务"
    echo "  status    显示服务状态"
    echo "  help      显示此帮助信息"
    echo
    echo "示例:"
    echo "  $0         # 优雅停止服务"
    echo "  $0 stop    # 优雅停止服务"
    echo "  $0 force   # 强制停止服务"
    echo "  $0 status  # 查看状态"
}

# 主函数
main() {
    case "${1:-stop}" in
        "stop")
            echo "=========================================="
            echo "    停止 $PROJECT_NAME 服务"
            echo "=========================================="
            echo
            
            # 检查服务是否运行
            if ! check_running; then
                log_info "服务未运行"
                exit 0
            fi
            
            PID=$(cat "$PID_FILE")
            log_info "停止服务 (PID: $PID)..."
            
            # 尝试优雅停止
            if graceful_stop "$PID" 30; then
                log_success "服务已优雅停止"
            else
                log_warning "优雅停止超时，尝试强制停止..."
                if force_stop "$PID"; then
                    log_success "服务已强制停止"
                else
                    log_error "无法停止服务，请手动处理"
                    exit 1
                fi
            fi
            
            # 清理PID文件
            cleanup_pid
            
            # 验证停止
            if show_status; then
                log_success "服务停止完成"
            else
                log_error "服务停止失败"
                exit 1
            fi
            ;;
        "force")
            echo "=========================================="
            echo "    强制停止 $PROJECT_NAME 服务"
            echo "=========================================="
            echo
            
            # 检查PID文件
            if [ -f "$PID_FILE" ]; then
                PID=$(cat "$PID_FILE")
                log_info "强制停止服务 (PID: $PID)..."
                force_stop "$PID"
                cleanup_pid
            fi
            
            # 通过端口停止
            stop_by_port
            
            log_success "强制停止完成"
            ;;
        "status")
            show_status
            ;;
        "help"|"-h"|"--help")
            show_help
            ;;
        *)
            log_error "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"
